<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
    </head>
    <body>
        <script>
            // 构造函数
            function Axios(config){
                this.config = config;
                this.interceptors = {
                    request:new InterceptorManager(),
                    response:new InterceptorManager()
                }
            }
            // 发送请求
            Axios.prototype.request = function(config){
                // 创建一个promise对象
                let promise= Promise.resolve(config);
                // 创建一个数组
                const chains = [dispatchRequest,undefined];
                // 处理拦截器
                // 请求拦截器 将请求拦截器的回到 压入到 chains的前面
                this.interceptors.request.handlers.forEach(item=>{
                    chains.unshift(item.fulfilled,item.rejected);
                })
                console.log(chains);
                // 响应拦截器
                this.interceptors.response.handlers.forEach(item=>{
                    chains.push(item.fulfilled,item.rejected);
                })
                console.log(chains);

                //遍历
                while(chains.length > 0){
                    promise = promise.then(chains.shift(),chains.shift());
                }
                return promise;
            }
            // 发送请求
            function dispatchRequest(config){
                // 返回一个promise 队形
                return new  Promise((resolve,reject)=>{
                    resolve({
                        status:200,
                        statusText:"ok"
                    })
                })
            }
            
            // 创建实例
            let context = new Axios({});
            //创建axios函数
            let axios = Axios.prototype.request.bind(context);
            // 将context实行config interceptors 添加至 axios函数对象上
            Object.keys(context).forEach(key =>{
                axios[key] = context[key];
            })
            //console.dir(axios);

            //拦截器管理器构造函数
            function InterceptorManager(){
                this.handlers = [];
            }
            InterceptorManager.prototype.use = function(fulfilled,rejected){
                this.handlers.push({
                    fulfilled,
                    rejected
                })
            }

            // 添加请求拦截器  config是配置对象
            axios.interceptors.request.use(function (config) {
                console.log("请求拦截器 成功1号");
                // 修改config中的参数
                config.params = {a:300};
                // 在发送请求之前做些什么
                return config;
            }, function (error) {
                console.log("请求拦截器 失败1号");
                // 对请求错误做些什么
                return Promise.reject(error);
            });
            axios.interceptors.request.use(function (config) {
                console.log("请求拦截器 成功2号");
                config.timeout = 2000;
                // 在发送请求之前做些什么
                return config;
            }, function (error) {
                console.log("请求拦截器 失败2号");
                // 对请求错误做些什么
                return Promise.reject(error);
            });

            // 添加响应拦截器
            axios.interceptors.response.use(function (response) {
                console.log("响应拦截器 成功1号");
                console.log(response);
                // 对响应数据做点什么
                return response;
            }, function (error) {
                console.log("响应拦截器 失败1号");
                // 对响应错误做点什么
                return Promise.reject(error);
            });
            // 添加响应拦截器
            axios.interceptors.response.use(function (response) {
                console.log("响应拦截器 成功2号");
                // 对响应数据做点什么
                return response;
            }, function (error) {
                console.log("响应拦截器 失败2号");
                // 对响应错误做点什么
                return Promise.reject(error);
            });

            console.dir(axios);

            //发送请求
            axios({
                method:"get",
                url:"http://127.0.0.1:3000/posts"
            }).then(response=>{
                console.log(response);
                console.log('自定义成功回调');
            }).catch(reason=>{
                console.log(reason);//参数出了问题
                console.log('自定义失败回调');
            })
        </script>
    </body>
</html>